<?php
/**
 * 抓取天气
 * 
 * @author xiongchuan <xiongchuan86@gmail.com>
 */
include('Signfork.class.php');
class GetWeatherCommand extends CConsoleCommand{
    
    public function run(){
        
        //把先前的数据全部置为过期
        $sql = "UPDATE {{weather}} SET is_new=0";
        Yii::app()->db->createCommand($sql)->execute();
        $rows = $this->getStationData();
        
        $processNum = 3;
        $rows = array_chunk($rows,30);
        //running
        echo "multi processes...\n";
        $limit      =microtime(true);
        $Signfork   =new Signfork();
        $results = $Signfork->run($this,$rows);
        echo 'Run time:'.(microtime(true)-$limit) . "\n";
        
        echo "Begin ReGetWeather......\n";
        $this->reGetWeather();
        echo "End ReGetWeather......\n";
        
        //删除过期的数据
        $sql = "DELETE FROM {{weather}} WHERE is_new=0";
        Yii::app()->db->createCommand($sql)->execute();
        echo "end \n";
        
        //把现在的数据置为可用状态is_new=0
        $sql = "UPDATE {{weather}} SET is_new=0";
        Yii::app()->db->createCommand($sql)->execute();
        $rows = $this->getStationData();
    }
    
    //子进程回调
    public function __fork($pid,$rows){
        $results = array();
        
        $sql = "INSERT INTO {{weather}} SET weather_id=:weather_id,weather=:weather,update_time=:update_time,is_new=1";
        $command = Yii::app()->db->createCommand($sql);
        foreach ($rows as $key => $value) {
            echo "pid:{$pid},cityid:{$value['weather_id']},city:{$value['name']}\n";
            try{
                $data    = $this->getWeather($value['weather_id']);
                $weather = $this->getCityWeather($data['weatherinfo']);
                $command->bindValue(":weather_id",$value['weather_id']);
                if(!$data){
                    $command->bindValue(":weather",'null');
                }else{
                    $command->bindValue(":weather",json_encode((array)$weather));
                }
                
                $command->bindValue(":update_time",time());
                $command->execute();
            }catch(exception $e){
                echo "getWeather FAILED;\n";
            }
        }
        return "";
    }
    
    //递归调用
    private function reGetWeather(){
        $sql = "SELECT * FROM {{weather}} WHERE weather='null' ORDER BY id ASC";
        $command1 = Yii::app()->db->createCommand($sql);
        $rows = $command1->queryAll();
        if($rows){
            $sql = "UPDATE {{weather}} SET weather=:weather WHERE weather_id=:weather_id";
            $command = Yii::app()->db->createCommand($sql);
            foreach ($rows as $value) {
                echo "reget,cityid:{$value['weather_id']}\n";
                try{
                    $data    = $this->getWeather($value['weather_id']);
                    $weather = $this->getCityWeather($data['weatherinfo']);
                    $command->bindValue(":weather_id",$value['weather_id']);
                    if(!$data){
                        $command->bindValue(":weather",'null');
                    }else{
                        $command->bindValue(":weather",json_encode((array)$weather));
                    }
                    $command->execute();
                }catch(exception $e){
                    print_r($e);
                    echo "getWeather FAILED;\n";
                }
            }
            $this->reGetWeather();
        }else{
            return ;
        }
    }
    
    
    /**
     * 从数据库获取地区列表
     * @return array 地区列表
     */
    private function getStationData(){
        //获取全部市和区
        //$sql = "SELECT * FROM {{china}} WHERE name_type='station'";
        //$command = Yii::app()->db->createCommand($sql);
        
        $sql = "SELECT * FROM w_china c1 LEFT JOIN w_china c2 ON c1.name=c2.name WHERE c1.name_type='city' AND c2.name_type='station'";
        $command = Yii::app()->db->createCommand($sql);
        return $command->queryAll();
    }
    
    /**
     * 从中国天气网抓取天气
     * @param int $weather_id 中国天气网的地区id
     * @return boolean|array 天气数据
     */
    private function getWeather($weather_id){
        //113.108.239.107 => m.weather.com.cn
        $url = "http://m.weather.com.cn/data/{$weather_id}.html";
        $result = Yii::app()->curl->run($url);
        $data = json_decode($result,true);
        return is_array($data) ? $data : false;
    }
    
    /**
     * 设置成天气格式
     * @param array $data  中国天气网的原始天气数据
     */
    private function getCityWeather($data){
        $cityWeather = new CityWeather();
        $cityWeather->city    = $data['city'];
        $cityWeather->city_en = $data['city_en'];
        $cityWeather->cityid  = $data['cityid'];
        for ($i=0; $i < 6; $i++) { 
            $cityWeather->weather[$i] = $this->getDayWeather($data, $i+1);
        }
        return $cityWeather;
    }
    
    /**
     * 从原始的天气数据里获取某一天的天气状况
     * @param array $data
     * @param int $day 1-6
     */
    private function getDayWeather($data,$day){
        $dayWeather = new DayWeather;
        $weeks = array(
        0=>'星期日',
        1=>'星期一',
        2=>'星期二',
        3=>'星期三',
        4=>'星期四',
        5=>'星期五',
        6=>'星期六',
        );
        preg_match("/(\d*)年(\d*)月(\d*)日/", $data['date_y'],$m);
        if(!empty($m)){
            if(1==$day){
                $dayWeather->date_year  = $m[1];
                $dayWeather->date_month = $m[2];
                $dayWeather->date_day   = $m[3];
                $dayWeather->date_week = (string)array_search($data['week'], $weeks);
            }else{
                $dayNum = $day - 1;
                $timestamp = strtotime("+{$dayNum}day",strtotime("{$m[1]}-{$m[2]}-{$m[3]}"));
                $dayWeather->date_year  = date("Y",$timestamp);
                $dayWeather->date_month = date("n",$timestamp);
                $dayWeather->date_day   = date("j",$timestamp);
                $dayWeather->date_week  = date("w",$timestamp);//$weeks[date("w",$timestamp)];
            }
        }
        $temp = explode("~",$data["temp".$day]);
        //echo "temp:".var_export($temp,true)."\n";
        $dayWeather->temp_h = str_replace("℃","",$temp[0]);
        $dayWeather->temp_l = str_replace("℃","",$temp[1]);
        $dayWeather->weather_day   = $data["img_title".(2*intval($day)-1)];
        $dayWeather->weather_night = $data["img_title".(2*intval($day))];
        $dayWeather->fxfl = $data["wind".$day];
        try{
            if(1==$day)$dayWeather->sd = $this->getCurrentWeatherSD($data['cityid']);
            else $dayWeather->sd = "";
        }catch(exception $e){
            $dayWeather->sd = "";
            echo "getCurrentWeatherSD  FAILD;\n";
        }
        
        return $dayWeather;
    }
    
    private function getCurrentWeatherSD($weather_id){
        //61.4.185.35 => www.weather.com.cn
        $url = "http://www.weather.com.cn/data/sk/{$weather_id}.html";
        $result = Yii::app()->curl->run($url);
        $data = json_decode($result,true);
        return is_array($data) ? $data['weatherinfo']['SD'] : "";
    }
    
}


/**
 * 某一天的具体天气状况
 */
class DayWeather{
    public $date_week;
    public $date_year;
    public $date_month;
    public $date_day;
    public $temp_h;
    public $temp_l;
    public $weather_day;
    public $weather_night;
    public $fxfl;//风向 风力
    public $sd;
}

/**
 * 城市天气
 */
class CityWeather{
    public $city;
    public $city_en;
    public $cityid;
    public $weather;//DayWeather
    
    public function __construct(){
        $this->weather = array();
    }
}
